package cn.ym.ymcc.exception;

import cn.ym.ymcc.enumcode.GlobleErrorCodeEnum;
import cn.ym.ymcc.result.JSONResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.stream.Collectors;

/**--------------------------------------------------------
全局异常处理
 @RestControllerAdvice ：控制器的增强注解
                    作用: 当控制器发生异常且符合类中定义的拦截异常类，将会被拦截
 --------------------------------------------------------**/
@RestControllerAdvice
@Slf4j
public class GlobleExceptionHandler {


    /**
     * 拦截系统异常：系统的一些综合异常
     */
    @ExceptionHandler(Exception.class)
    public JSONResult systemException(Exception e){
        e.printStackTrace();//打印具体的错误信息
        return JSONResult.error(GlobleErrorCodeEnum.SYSTEM_ERROR);
    }

    /**
     * 算数异常
     * @param e
     * @return
     */
    @ExceptionHandler(ArithmeticException.class)
    public JSONResult arithmeticException(ArithmeticException e){
        e.printStackTrace();//打印具体的错误信息
        return JSONResult.error("算数异常","11111");
    }

    /**
     * 运行时异常
     * @param e
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public JSONResult RuntimeException(RuntimeException e){
        e.printStackTrace();//打印具体的错误信息
        return JSONResult.error(e.getMessage());
    }

    /**
     * 拦截自定义的异常:  这个注解就可以拦截器 BusinessException 异常
     *
     */
    @ExceptionHandler(BusinessException.class)
    public JSONResult businessException(BusinessException e){
        e.printStackTrace();//打印具体的错误信息
        return JSONResult.error(e.getMessage(),GlobleErrorCodeEnum.BUSINESS_ERROR.getCode());
    }



    /**
     * 第一种：原生
     * 添加的时候数据不合法 对JSR303支持
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    //1.拿到所有的错误异常
    public JSONResult jsr303Exception(MethodArgumentNotValidException e){
        e.printStackTrace();//打印具体的错误信息
        //字符串缓冲对象
        StringBuffer buffer = new StringBuffer();
        //获取所有的错误信息
        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
        //遍历使用错误信息
        allErrors.forEach(err->{
            //err.getDefaultMessage();//取出来了每一个错误
            //把错误信息拼接到一起
            buffer.append(err.getDefaultMessage()).append(";");
        });
        return JSONResult.error(buffer.toString(),GlobleErrorCodeEnum.PARAM_ERROR.getCode());
    }

    /**
     *
     * 第二章种
     *      Stream流：Java新特性
     * @param e
     * @return
     */

//    @ExceptionHandler(value = MethodArgumentNotValidException.class)
//    public JSONResult handlerMethodArgumentNotValidException(MethodArgumentNotValidException e){
//        e.printStackTrace();
//        /**2.提取所有的错误信息*/
//        String errorMsg = e.getBindingResult().getAllErrors()
//                .stream().map(ObjectError::getDefaultMessage)
//                .collect(Collectors.joining(";"));
//
//        return JSONResult.error(errorMsg);
//    }


}